﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Imgur.Net.Auth;
using NUnit.Framework;

namespace Imgur.Net.Test.Auth
{
    [TestFixture]
    public class AuthUtilsTests
    {
        [Test]
        public void CreateInstance()
        {
            var instance = new AuthUtils();
            Assert.IsNotNull(instance);
        }

        [Test]
        public void CheckRegisteredAuthStateIsExpired()
        {
            var instance = new AuthUtils();
            Assert.IsNotNull(instance);

            RegistrationTokenContext testContext = new DefaultRegistrationTokenContext(
                "aaa",
                "rrrr",
                DateTime.Now.AddSeconds(-200));

            RegisteredAuthorizationState result = instance.CheckRegisteredAuthorizationTokenState(testContext);

            Assert.AreEqual(RegisteredAuthorizationState.RequiresLoginExpired, result);
        }

        [Test]
        public void CheckRegisteredAuthStateAuthExists()
        {
            var instance = new AuthUtils();
            Assert.IsNotNull(instance);

            RegistrationTokenContext testContext = new DefaultRegistrationTokenContext(
                "aaa",
                "rrrr",
                DateTime.Now.AddSeconds(200));

            RegisteredAuthorizationState result = instance.CheckRegisteredAuthorizationTokenState(testContext);

            Assert.AreEqual(RegisteredAuthorizationState.AuthorizationExists, result);
        }

        [Test]
        public void CheckRegisteredAuthStateNoAccessToken()
        {
            var instance = new AuthUtils();
            Assert.IsNotNull(instance);

            RegistrationTokenContext testContext = new DefaultRegistrationTokenContext(
                "",
                "rrrr",
                DateTime.Now.AddSeconds(200));

            RegisteredAuthorizationState result = instance.CheckRegisteredAuthorizationTokenState(testContext);

            Assert.AreEqual(RegisteredAuthorizationState.RequiresLoginNoAccessToken, result);
        }

        [Test]
        public void CheckRegisteredAuthStateNoRefreshToken()
        {
            var instance = new AuthUtils();
            Assert.IsNotNull(instance);

            RegistrationTokenContext testContext = new DefaultRegistrationTokenContext(
                "aaa",
                "",
                DateTime.Now.AddSeconds(-200));

            RegisteredAuthorizationState result = instance.CheckRegisteredAuthorizationTokenState(testContext);

            Assert.AreEqual(RegisteredAuthorizationState.RequiresLoginNoRefreshToken, result);
        }

        [Test]
        [ExpectedException(typeof(ArgumentNullException))]
        public void ParseOAuthResponseNullUri()
        {
            Uri uri = null;

            var instance = new AuthUtils();
            Assert.IsNotNull(instance);

            instance.ParseOAuthResponse(uri);
        }

        [Test]
        [ExpectedException(typeof(LoginException))]
        public void ParseOAuthResponseInvalidResponse()
        {
            const string invalidResponse = "http://example.com/login.do";

            Uri uri = new Uri(invalidResponse);

            var instance = new AuthUtils();
            Assert.IsNotNull(instance);

            RegistrationTokenContext result = instance.ParseOAuthResponse(uri);

        }

        [Test]
        public void ParseOAuthResponseValidResponse()
        {
            const string validResponse = "http://example.com#access_token=ACCESSTOKEN&refresh_token=REFRESHTOKEN&expires_in=3600";

            const string invalidResponse = "http://example.com/login.do";

            Uri uri = new Uri(validResponse);

            var instance = new AuthUtils();
            Assert.IsNotNull(instance);

            RegistrationTokenContext result = instance.ParseOAuthResponse(uri);

            Assert.IsNotNull(result);
            Assert.AreEqual("ACCESSTOKEN", result.AccessToken);
            Assert.AreEqual("REFRESHTOKEN", result.RefreshToken);
            Assert.GreaterOrEqual( 10, ( DateTime.Now - result.Expiration ).Seconds);
        }
    }
}
